package com.lank.gateway.config;

import com.lank.gateway.config.service.impl.CustomAccessDeniedHandler;
import com.lank.gateway.config.service.impl.CustomAuthenticationEntryPoint;
import com.lank.gateway.config.service.impl.CustomAuthorizationManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

import javax.annotation.Resource;

/**
 * springGateway中的oauth2配置
 *
 * @author root
 */
@EnableWebFluxSecurity
public class ConfigSecurity {

    @Resource
    CustomAuthorizationManager authorizationManager;
    @Resource
    CustomAccessDeniedHandler accessDeniedHandler;
    @Resource
    CustomAuthenticationEntryPoint authenticationEntryPoint;
    @Value("${spring.security.whitelist}")
    private String[] whitelist;

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) {
        http.oauth2ResourceServer()
                .accessDeniedHandler(accessDeniedHandler)
                .authenticationEntryPoint(authenticationEntryPoint)
                .jwt()
        ;
        http.cors().disable();
        http.csrf().disable();
        http.authorizeExchange()
                .pathMatchers(whitelist).permitAll()
                .anyExchange().access(authorizationManager);
        http.addFilterAt(corsWebFilter(), SecurityWebFiltersOrder.SECURITY_CONTEXT_SERVER_WEB_EXCHANGE);
        return http.build();
    }

    @Bean
    public CorsResponseHeaderFilter corsResponseHeaderFilter() {
        return new CorsResponseHeaderFilter();
    }

    @Bean
    public CorsWebFilter corsWebFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.setMaxAge(1800L);
        corsConfiguration.setAllowCredentials(true);

        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsWebFilter(source);
    }
}
